package org.coffeebreaks.james.mailets.directory;

/**
 * Copyright 2008 Jerome Lacoste.
 *
 * Licensed under the Apache License, Version 2.0 (the "License" );
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.atlassian.crowd.integration.service.soap.client.SecurityServerClient;
import com.atlassian.crowd.integration.soap.SOAPGroup;
import com.atlassian.crowd.integration.soap.SOAPPrincipal;
import com.atlassian.crowd.integration.soap.SOAPAttribute;

import java.util.List;
import java.util.ArrayList;

/**
 * A directory service implemented in a Crowd directory server.
 *
 * @author jerome@coffeebreaks.org
 * 
 * @link http://ww.atlassian.com/products/crowd
 */
public class CrowdDirectoryService implements DirectoryService {
  // TODO we lack the ability to not depend on the crowd.properties file.... This should be fixed with crowd 1.3

  public String getUserEmail(String username) {
    try {
      SOAPPrincipal principal = SecurityServerClient.findPrincipalByName(username);
      if (principal == null) {
        return null;
      }
      return getPrincipalEmail(principal);
    } catch (Exception e) {
      throw new RuntimeException("Failure to get member email for username" + username, e);
    }
  }

  public String[] getGroupEmails(String groupname) {
    try {
      SOAPGroup group = SecurityServerClient.findGroupByName(groupname);
      String[] members = group.getMembers();
      List<String> emails = new ArrayList<String>();

      for (String member : members) {
        SOAPPrincipal principal = SecurityServerClient.findPrincipalByName(member);
        if (principal == null) {
          throw new IllegalStateException("member " + member + " found in group " + groupname + " but not in crowd.");
        }
        String email = getPrincipalEmail(principal);
        emails.add(email);
      }
      return emails.toArray(new String[emails.size()]);
    }
    catch (Exception e) {
      throw new RuntimeException("Failure to get group member emails for group " + groupname, e);
    }
  }

  private String getPrincipalEmail(SOAPPrincipal principal) {
    String email = getPrincipalAttributeValue(principal, "mail");
    if (email == null) {
      throw new IllegalStateException("Found member without email! " + principal.getName());
    }
    return email;
  }

  private String getPrincipalAttributeValue(SOAPPrincipal principal, String attributeName) {
    SOAPAttribute[] attributes = principal.getAttributes();
    String email = null;
    for (SOAPAttribute attribute : attributes) {
      if (attribute.getName().equals(attributeName)) {
        email = attribute.getValues()[0];
        break;
      }
    }
    return email;
  }
}
